package cn.itcast.nems.studentrecord.service.impl.studentrecord;

import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.common.enumeration.NemsErrorBodyEnum;
import cn.itcast.nems.journal.api.JournalRenewalApi;
import cn.itcast.nems.journal.api.JournalTransferApi;
import cn.itcast.nems.journal.api.JournalTransferLineDiscountApi;
import cn.itcast.nems.journal.dto.JournalRenewalDTO;
import cn.itcast.nems.journal.dto.JournalTransferDTO;
import cn.itcast.nems.journal.dto.JournalTransferLineDiscountDTO;
import cn.itcast.nems.journal.service.JournalRenewalLineDiscountService;
import cn.itcast.nems.journal.service.JournalRenewalOrderRelationshipService;
import cn.itcast.nems.journal.service.JournalTransferOrderRelationshipService;
import cn.itcast.nems.order.api.JournalDiscountApi;
import cn.itcast.nems.order.api.OrderApi;
import cn.itcast.nems.order.dao.entity.OrderCustomerRelationship;
import cn.itcast.nems.order.dto.JournalDiscountApiReqDTO;
import cn.itcast.nems.order.dto.OrderMode;
import cn.itcast.nems.order.dto.OrderModeDiscountDTO;
import cn.itcast.nems.order.service.OrderCustomerRelationshipService;
import cn.itcast.nems.studentrecord.constant.DiscountScopeTypeEnum;
import cn.itcast.nems.studentrecord.dao.entity.JournalRenewalOrderRelationship;
import cn.itcast.nems.studentrecord.dao.entity.JournalTransferOrderRelationship;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecordStudentRelationship;
import cn.itcast.nems.studentrecord.enumeration.StudentRecordSourceEnum;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordStudentRelationshipService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordValidService;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Slf4j
public class StudentRecordValidServiceImpl implements StudentRecordValidService {
    private final StudentRecordService studentRecordService;
    private final JournalDiscountApi journalDiscountApi;
    private final StudentRecordStudentRelationshipService studentRecordStudentRelationshipService;
    private final JournalRenewalLineDiscountService journalRenewalLineDiscountService;
    private final JournalRenewalOrderRelationshipService journalRenewalOrderRelationshipService;
    private final JournalRenewalApi journalRenewalApi;
    private final JournalTransferOrderRelationshipService journalTransferOrderRelationshipService;
    private final JournalTransferLineDiscountApi journalTransferLineDiscountApi;
    private final JournalTransferApi journalTransferApi;
    private final OrderCustomerRelationshipService orderCustomerRelationshipService;
    private final OrderApi orderApi;

    @Override
    public void writeOff(String recordId) {
        log.info("【学籍生效】进入核销业务逻辑 ，学籍ID：{}", recordId);
        StudentRecord studentRecord = studentRecordService.getById(recordId);
        Assert.notNull(studentRecord, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "学籍ID：" + recordId));
        List<StudentRecordStudentRelationship> list = studentRecordStudentRelationshipService.findByStudentRecordId(recordId);
        Assert.notEmpty(list, String.format("学籍ID：%s 对应的学籍学生记录不存在", recordId));
        switch (StudentRecordSourceEnum.valueOf(studentRecord.getSource())) {
            case RENEWAL -> {
                log.info("【学籍生效】升级核销， 学籍详情：{}", JSON.toJSONString(studentRecord));
                List<JournalRenewalOrderRelationship> orderRelationships = journalRenewalOrderRelationshipService.findListByRecordId(recordId);
                Assert.notEmpty(orderRelationships, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "学籍ID：" + recordId + " 对应升级凭单和订单的关系记录"));
                JournalRenewalDTO journalRenewalDTO = journalRenewalApi.getById(orderRelationships.get(0).getJournalRenewalId());
                log.info("【学籍生效】升级核销， 凭单详情：{}", JSON.toJSONString(journalRenewalDTO));
                List<String> discounts = journalRenewalLineDiscountService.findListByRenewalIdAndLineId(orderRelationships.get(0).getJournalRenewalId(), orderRelationships.get(0).getJournalRenewalLineId());
                log.info("【学籍生效】升级核销， 优惠单列表：{}", JSON.toJSONString(discounts));
                Objects.requireNonNullElse(discounts, new ArrayList<String>())
                        .forEach(
                                v -> {
                                    JournalDiscountApiReqDTO apiReqDTO = JournalDiscountApiReqDTO.buildForWriteOff(v, list.get(0).getStudentId(), null, studentRecord.getClazzId(), journalRenewalDTO.getCreatedDatetime(), JournalDiscountApiReqDTO.Scenario.RENEWAL);
                                    log.info("【调用个人优惠单核销接口】升级凭单 请求参数：{}", JSON.toJSONString(apiReqDTO));
                                    journalDiscountApi.writeOff(apiReqDTO);
                                }
                        );

            }
            case TRANSFER,EXCHANGE -> {
                log.info("【学籍生效】转班核销， 学籍详情：{}", JSON.toJSONString(studentRecord));
                List<JournalTransferOrderRelationship> orderRelationships = journalTransferOrderRelationshipService.findListByRecordId(recordId);
                Assert.notEmpty(orderRelationships, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "学籍ID：" + recordId + " 对应转班凭单和订单的关系记录"));
                JournalTransferDTO journalTransferDTO = journalTransferApi.getById(orderRelationships.get(0).getJournalTransferId());
                List<JournalTransferLineDiscountDTO> discounts = journalTransferLineDiscountApi.findListByTransferIdAndLineId(orderRelationships.get(0).getJournalTransferId(), orderRelationships.get(0).getJournalTransferLineId());
                log.info("【学籍生效】升级核销， 优惠单列表：{}", JSON.toJSONString(discounts));
                Objects.requireNonNullElse(discounts, new ArrayList<JournalTransferLineDiscountDTO>()).stream()
                        .filter(v -> DiscountScopeTypeEnum.PERSONAL.name().equalsIgnoreCase(v.getDiscountScopeType()))
                        .forEach(
                                v -> {
                                    JournalDiscountApiReqDTO apiReqDTO = JournalDiscountApiReqDTO.buildForWriteOff(v.getJournalDiscountLineId(), list.get(0).getStudentId(), null, studentRecord.getClazzId(), journalTransferDTO.getCreatedDatetime(), JournalDiscountApiReqDTO.Scenario.TRANSFER);
                                    log.info("【调用个人优惠单核销接口】转班凭单 请求参数：{}", JSON.toJSONString(apiReqDTO));
                                    journalDiscountApi.writeOff(apiReqDTO);
                                }
                        );
            }
            case NEW -> {
                String orderId = studentRecordService.findOrderId(recordId);
                Assert.notEmpty(orderId, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "通过学籍ID查询订单ID在"));
                OrderCustomerRelationship orderCustomerRelationship = orderCustomerRelationshipService.queryByOrderId(orderId);
                Assert.notNull(orderCustomerRelationship, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "订单与客户关联关系在"));
                OrderMode orderMode = orderApi.findById(orderId);
                Assert.notNull(orderCustomerRelationship, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "订单在"));
                final List<OrderModeDiscountDTO> discounts = orderApi.findOrderDiscounts(orderId);
                discounts.stream()
                        .filter(o -> StringUtils.hasText(o.getJournalDiscountLineId()))
                        .forEach(o -> {
                            JournalDiscountApiReqDTO apiReqDTO = JournalDiscountApiReqDTO.buildForWriteOff(
                                    o.getJournalDiscountLineId(),
                                    null,
                                    orderCustomerRelationship.getCustomerId(),
                                    studentRecord.getClazzId(),
                                    orderMode.getCreatedDatetime(),
                                    JournalDiscountApiReqDTO.Scenario.EMPLOYEE_SIGN_UP
                            );
                            log.info("【调用个人优惠单核销接口】新学员学籍生效 请求参数：{}", JSON.toJSONString(apiReqDTO));
                            journalDiscountApi.writeOff(apiReqDTO);
                        });
            }
        }
    }
}
